《嵌入式系统 – 玩转中科蓝讯(AB32VG1)开发板(基于RT-Thread系统)》第3章 串口设备的使用

开发环境:
RT-Thread版本:4.0.3
操作系统:Windows 10
RT-Thread Studio版本:2.0.0
开发板MCU:AB5301A

RTT 中外设作为设备存在,在建立工程的时候,AB32VG1串口0被作为系统调试串口,假如现在有一个串口模块需要和单片机通讯,则可以再初始化一个串口。如果没有驱动,那么第一步就需要写驱动,针对AB32VG1开发板,已经写好的UART驱动设备,只需要打开相应的设备即可。

3.1串口设备的简单使用

3.1.1实现串口的收发

UART0已经被用作了下载和调试串口,因此这里使用UART1。我们先来看看电路。

6yIjPA.png

从电路图可以看出,这里使用的PA3和PA4,因此需要将PA3和PA4通过USB转串口接到PC上通过串口调试助手查看收发信息。

该工程默认使能了UART0和UART1,通过finish终端也能看到UART的设备。

6yIzxP.png

这里直接写应用代码就行。在applications新建task.ctask.h文件。

[task.c]

/**
  ******************************************************************************
  * @file                task.c
  * @author              BruceOu
  * @lib version         V3.5.0
  * @version             V1.0
  * @date                2021-01-10
  * @blog                https://blog.bruceou.cn/
  * @Official Accounts   嵌入式实验楼
  * @brief               RTT任务
  ******************************************************************************
  */
/*Includes**********************************************************************/
#include "task.h"

struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;  /* 初始化配置参数 */

/* 用于接收消息的信号量 */
static struct rt_semaphore rx_sem;
static rt_device_t serial;

/**
  * @brief  uart_input //接收数据回调函数
  * @param  dev
  *         size
  * @retval RT_EOK
  */
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
    /* 串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */
    rt_sem_release(&rx_sem);

    return RT_EOK;
}

/**
  * @brief  serial_thread_entry
  * @param  parameter
  * @retval None
  */
static void serial_thread_entry(void *parameter)
{
    char ch;

    while (1)
    {
        /* 从串口读取一个字节的数据,没有读取到则等待接收信号量 */
        while (rt_device_read(serial, -1, &ch, 1) != 1)
        {
            /* 阻塞等待接收信号量,等到信号量后再次读取数据 */
            rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
        }
        /* 读取到的数据输出 */
        rt_kprintf("%c",ch);
    }
}

/**
  * @brief  thread_serial
  * @param  None
  * @retval ret
  */
int thread_serial(void)
{
    rt_err_t ret = RT_EOK;
    char uart_name[RT_NAME_MAX];
    char str[] = "hello RT-Thread!\r\n";

    rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX);

    /* 查找系统中的串口设备 */
    serial = rt_device_find(uart_name);
    if (!serial)
    {
        rt_kprintf("find %s failed!\n", uart_name);
        return RT_ERROR;
    }
    /* 修改串口配置参数 */
    config.baud_rate = BAUD_RATE_9600;        //修改波特率为 9600
    config.data_bits = DATA_BITS_8;           //数据位 8
    config.stop_bits = STOP_BITS_1;           //停止位 1
    config.bufsz     = 64;                   //修改缓冲区 buff size 为 128
    config.parity    = PARITY_NONE;           //无奇偶校验位

    /* 控制串口设备。通过控制接口传入命令控制字,与控制参数 */
    rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);

    /* 初始化信号量 */
    rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
    /* 以中断接收及轮询发送模式打开串口设备 */
    rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);
    /* 设置接收回调函数 */
    rt_device_set_rx_indicate(serial, uart_input);
    /* 发送字符串 */
    rt_device_write(serial, 0, str, (sizeof(str) - 1));

    /* 创建 serial 线程 */
    rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10);
    /* 创建成功则启动线程 */
    if (thread != RT_NULL)
    {
        rt_thread_startup(thread);
    }
    else
    {
        ret = RT_ERROR;
    }

    return ret;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(thread_serial, uart device sample);

[task.h]

#ifndef _TASK_H_
#define _TASK_H_

/* Standard includes. */
#include <stdio.h>

/* rtthread includes. */
#include <rtdevice.h>
#include <board.h>

#define SAMPLE_UART_NAME                 "uart1"

int thread_serial(void);

#endif

代码很简单,创建了一个线程,在线程中使用了中断接收以及轮询数据,主要函数如下:

rt_device_find()    //查找设备
rt_device_open()     //打开设备
rt_device_read()    //读取数据
rt_device_write()   //写入数据
rt_device_control() //控制设备
rt_device_set_rx_indicate() //设置接收回调函数
rt_device_set_tx_complete() //设置发送完成回调函数
rt_device_close()    //关闭设备

3.1.2实验现象

编译,下载。在finish终端输入thread_serial

6yoiVg.png

使用串口调试助手即可查看uart1的输出信息。

6yok5j.png

同样也可通过串口调试助手发送数据,finish终端可看到接收的数据。

6yoEPs.png

关于UART应用程序的详细使用请移步RTT文档中心。

UART 设备

3.2串口设备优化

熟悉RTT的都知道,RTT中的所有设备都是通过宏定义来开关设备,但是AB32VG1该部分没有完善,那么要怎么做才能和其他BSP一样可通过配置的方式来开关UART设备呢?接下来就一一讲解。

首先我们要知道AB32VG1的UART初始化调用的是drv_uart.c中rt_hw_usart_init()函数。

6yoZ2q.png

这里uart_config定义了UART的基地址,同时决定了UART的大小,因此,需要将该变量的定义修改如下:

6yourT.png

其实就增加了几条宏,同样将枚举修改如下:

6yoaqO.png

另外还需要修改UART的中断函数:

6yowZD.png

接下来我们就可以通过

#define BSP_USING_UART0
#define BSP_USING_UART1

控制UART设备的打开和关闭。到这里还没有完,要想实现可是话的配置还需要修改board的Kconfig文件,修改后的内容如下:

6yo2sf.png

到此就修改完了,接下来就可使用刚才的配置了。这里RT-Thread Studio配置,打开RT-Thread Setting,就可进行UART的配置了。

6yovo4.png

至于UART0为了不能取消配置,是因为UART0做了调试串口,已经强制配置了。

当然,也可ENV工具配置,进入工程目录,打开env控制台,输入 menuconfig 命令后即可打开其界面。依次进入以下选项:

→ Hardware Drivers Config → On-chip Peripheral → Enable UART

使能UART1,保存退出即可。

6yooJs.png

和RT-Thread Studio添加串口设备的结果一样,最终都会在rtconfig.h中添加以下宏定义。

6yoLLT.png

好了,串口设备的优化就到这里了。现在UART设备就可以打开和关闭。

Related posts

Leave a Comment